`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/11/20 10:12:11
// Design Name: 
// Module Name: ddr3_wr_rd
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module ddr3_wr_rd(

    inout [31:0] ddr3_dq,
    inout [3:0]  ddr3_dqs_n,
    inout [3:0]  ddr3_dqs_p,
    
    output [13:0] ddr3_addr,
    output [2:0] ddr3_ba,
    output       ddr3_ras_n,
    output       ddr3_cas_n,
    output       ddr3_we_n,
    output       ddr3_reset_n,
    output       ddr3_ck_p,
    output       ddr3_ck_n,
    output       ddr3_cke,
    output       ddr3_cs_n,
    output       [3:0]  ddr3_dm,
    output       ddr3_odt,
    
    //output       init_calib_complete,
    input        clk50m_i
    //output wire      init_calib_complete
    
    );
    
    wire    ui_clk;
    wire    ui_clk_sync_rst;
    wire init_calib_complete;
	
	wire       app_rd_data_valid;/////////////////
	wire [255:0]  app_rd_data;/////////////////////
	wire      app_rd_data_end;///////////////////
		
	wire    rst_n_i;
    assign 	rst_n_i = (~ui_clk_sync_rst) | (~init_calib_complete);
	
	reg [4:0] rst_tem = 5'd0;
	
	always @ (posedge ui_clk)
	begin
		rst_tem <= {rst_tem[3:0],rst_n_i};
	end 
    
	parameter IDLE = 6'd1;
	parameter WRITE = 6'd2;
	parameter READ  = 6'd3;
	parameter WRITE_WAIT = 6'd4;
	parameter READ_WAIT = 6'd5;
	parameter END = 6'd6;
    parameter   CNT_MAX = 25'd16777216;
    
    reg [5:0] state;
    reg [24:0] write_cnt;
    reg [24:0] read_cnt;
    reg [31:0] cnt_zong;
    reg [31:0]  cnt_rd;
    
    reg [28:0] ddr3_addr_write_r;
    reg [28:0] ddr3_addr_read_r;
    
    wire WRITE_FLAG = (state == WRITE)? 1'b1 : 1'b0;
    wire READ_FLAG = (state == READ)? 1'b1 : 1'b0;
    wire IDLE_FLAG = (state == IDLE)? 1'b1 : 1'b0;
    wire WRITE_WAIT_FLAG = (state == WRITE_WAIT)? 1'b1 : 1'b0;
    wire READ_WAIT_FLAG = (state == READ_WAIT)? 1'b1 : 1'b0;
    wire END_FLAG = (state == END)? 1'b1 : 1'b0;
    
    wire app_rdy;
    wire app_wdf_rdy ;
    
    always @ (posedge ui_clk)
	begin
		if(!rst_tem[4])
			begin
				state <= IDLE;
				write_cnt <= 25'd0;
				read_cnt <= 25'd0;
				ddr3_addr_write_r <= 29'd0;
				ddr3_addr_read_r <= 29'd0;
			end 
		else if(init_calib_complete) //如果初始化完成之后，开始进行读写操作
			begin 
				case(state)
			
					IDLE:
						begin
							state <= WRITE;
							// write_cnt <= 32'd0;
							// read_cnt <= 32'd0;
							// ddr3_addr_write_r <= 15'd0;
							// ddr3_addr_read_r <= 15'd0;
						end 
			
					WRITE:
						begin
							//if(app_rdy&& app_wdf_rdy)
								//begin
									//write_cnt <= (write_cnt == 32'd1024)? write_cnt : (write_cnt + 32'd1);
									//state <= (write_cnt == 32'd1024)? WRITE_WAIT :state;
									ddr3_addr_write_r <= (app_rdy&&app_wdf_rdy)?(ddr3_addr_write_r + 29'd8):ddr3_addr_write_r;
									state <= (app_rdy&&app_wdf_rdy&&(write_cnt==CNT_MAX-1)) ? READ : state;
									write_cnt <= (app_rdy&&app_wdf_rdy)?(write_cnt + 16'd1):write_cnt;
									
									// if(app_rdy&&app_wdf_rdy)
										// begin
											// if(write_cnt==10'd1023)
												// begin
													// write_cnt <= write_cnt;
													// state <= WRITE_WAIT;
												// end 
											// else
												// begin
													// write_cnt <= write_cnt + 10'd1;
													// state <= state;
												// end 
										// end 
									
								//end 
							// else
								// begin
									// state <= state;
									// write_cnt <= write_cnt;
									// ddr3_addr_write_r <= ddr3_addr_write_r;
								// end 
						end 
					WRITE_WAIT:
						begin
							state <= READ;
						end 
						
					READ:
						begin
							//if(app_rdy)
							//	begin
									//read_cnt <= (read_cnt == 32'd1024)? read_cnt : (read_cnt + 32'd1);
									//state <= (read_cnt == 32'd1024)? READ_WAIT :state;
									//ddr3_addr_read_r <= ddr3_addr_read_r + 15'd1;
									ddr3_addr_read_r <= (app_rdy)?(ddr3_addr_read_r + 29'd8):ddr3_addr_read_r;
									state <= (app_rdy&&(read_cnt==CNT_MAX-1)) ? END : state;
									read_cnt <= (app_rdy&&app_wdf_rdy)?(read_cnt + 16'd1):read_cnt;
									
									// if(app_rdy)
										// begin
											// if(read_cnt==10'd1023)
												// begin
													// read_cnt <= read_cnt;
													// state <= READ_WAIT;
												// end 
											// else
												// begin
													// read_cnt <= read_cnt + 10'd1;
													// state <= state;
												// end 
										// end 
							//	end 
							// else
								// begin
									// ddr3_addr_read_r <= ddr3_addr_read_r;
									// read_cnt <= read_cnt;
									// state <= state;
								// end 
						end 
					READ_WAIT:
						begin
							state <= END;
						end 
						
					END:
						begin
							state <= IDLE;
							write_cnt <= 25'd0;
							read_cnt <= 25'd0;
							ddr3_addr_write_r <= 29'd0;
							ddr3_addr_read_r <= 29'd0;
						end 
					default:
						begin
							state <= IDLE;
							write_cnt <= 25'd0;
							read_cnt <= 25'd0;
							ddr3_addr_write_r <= 29'd0;
							ddr3_addr_read_r <= 29'd0;
						end 
						
						
						
				endcase
			end 
	end 
	
	wire  [27:0]		app_addr;
	wire  [2:0]		    app_cmd;
	wire                app_en;
	wire  [255:0]		app_wdf_data;
	wire                app_wdf_end;
	wire                app_wdf_wren;
	
	wire                app_sr_active;
	wire                app_ref_ack;
	wire                app_zq_ack;

	assign app_wdf_end = app_wdf_wren;
	//assign app_en = ((state == WRITE)||(state == WRITE_WAIT))? (app_rdy&& app_wdf_rdy) : ((state == READ) || (state == READ_WAIT) && app_rdy);
	assign app_en = (state == WRITE)? (app_rdy&&app_wdf_rdy) : ((state == READ)&& app_rdy);
	//assign app_cmd = ((state == WRITE)||(state == WRITE_WAIT))? 3'd0 : 3'd1;
	assign app_cmd = (state == WRITE)? 3'b0 : 3'b1;
	assign app_wdf_data = {239'b0,write_cnt};
	//assign app_wdf_wren = ((state == WRITE)||(state == WRITE_WAIT)) && app_rdy && app_wdf_rdy;
	assign app_wdf_wren = (state == WRITE) && app_rdy && app_wdf_rdy;
	//assign app_addr = ((state == WRITE)||(state == WRITE_WAIT))? (ddr3_addr_write_r) : (ddr3_addr_read_r);
	assign app_addr = (state == WRITE)? (ddr3_addr_write_r) : (ddr3_addr_read_r);
		
	wire clk_ref_i;
	wire sys_clk_i;
	wire clk_200m;
	assign clk_ref_i = clk_200m;
	assign sys_clk_i = clk_200m;
    
    
    always @ (posedge ui_clk)
		if(!rst_tem[4])
            cnt_zong <= 32'd0;
        else    if((~WRITE_FLAG)&&(READ_FLAG))
            cnt_zong <= 32'd0;
        else    if(WRITE_FLAG)
            cnt_zong <= cnt_zong + 1'b1;
        else
            cnt_zong <= cnt_zong;
            
     always @ (posedge ui_clk)
		if(!rst_tem[4])
            cnt_rd <= 32'd0;
        else    if((WRITE_FLAG)&&(~READ_FLAG))
            cnt_rd <= 32'd0;
        else    if(READ_FLAG)
            cnt_rd <= cnt_rd + 1'b1;
        else
            cnt_rd <= cnt_rd;        
            
    
    
    clk_wiz_0 clk_wiz_0
   (
    // Clock out ports
    .clk_out1(clk_200m),     // output clk_out1
    // Status and control signals
    .locked(locked),       // output locked
   // Clock in ports
    .clk_in1(clk50m_i));      // input clk_in1
    
    
    

    
    
      mig_7series_0 u_mig_7series_0 (

    // Memory interface ports
    .ddr3_addr                      (ddr3_addr),  // output [13:0]		ddr3_addr
    .ddr3_ba                        (ddr3_ba),  // output [2:0]		ddr3_ba
    .ddr3_cas_n                     (ddr3_cas_n),  // output			ddr3_cas_n
    .ddr3_ck_n                      (ddr3_ck_n),  // output [0:0]		ddr3_ck_n
    .ddr3_ck_p                      (ddr3_ck_p),  // output [0:0]		ddr3_ck_p
    .ddr3_cke                       (ddr3_cke),  // output [0:0]		ddr3_cke
    .ddr3_ras_n                     (ddr3_ras_n),  // output			ddr3_ras_n
    .ddr3_reset_n                   (ddr3_reset_n),  // output			ddr3_reset_n
    .ddr3_we_n                      (ddr3_we_n),  // output			ddr3_we_n
    .ddr3_dq                        (ddr3_dq),  // inout [31:0]		ddr3_dq
    .ddr3_dqs_n                     (ddr3_dqs_n),  // inout [3:0]		ddr3_dqs_n
    .ddr3_dqs_p                     (ddr3_dqs_p),  // inout [3:0]		ddr3_dqs_p
    .init_calib_complete            (init_calib_complete),  // output			init_calib_complete
      
	.ddr3_cs_n                      (ddr3_cs_n),  // output [0:0]		ddr3_cs_n
    .ddr3_dm                        (ddr3_dm),  // output [3:0]		ddr3_dm
    .ddr3_odt                       (ddr3_odt),  // output [0:0]		ddr3_odt
    // Application interface ports
    .app_addr                       (app_addr),  // input [27:0]		app_addr
    .app_cmd                        (app_cmd),  // input [2:0]		app_cmd
    .app_en                         (app_en),  // input				app_en
    .app_wdf_data                   (app_wdf_data),  // input [255:0]		app_wdf_data
    .app_wdf_end                    (app_wdf_end),  // input				app_wdf_end
    .app_wdf_wren                   (app_wdf_wren),  // input				app_wdf_wren
    .app_rd_data                    (app_rd_data),  // output [255:0]		app_rd_data
    .app_rd_data_end                (app_rd_data_end),  // output			app_rd_data_end
    .app_rd_data_valid              (app_rd_data_valid),  // output			app_rd_data_valid
    .app_rdy                        (app_rdy),  // output			app_rdy
    .app_wdf_rdy                    (app_wdf_rdy),  // output			app_wdf_rdy
    .app_sr_req                     (1'b0),  // input			app_sr_req
    .app_ref_req                    (1'b0),  // input			app_ref_req
    .app_zq_req                     (1'b0),  // input			app_zq_req
    .app_sr_active                  (app_sr_active),  // output			app_sr_active
    .app_ref_ack                    (app_ref_ack),  // output			app_ref_ack
    .app_zq_ack                     (app_zq_ack),  // output			app_zq_ack
    .ui_clk                         (ui_clk),  // output			ui_clk
    .ui_clk_sync_rst                (ui_clk_sync_rst),  // output			ui_clk_sync_rst
    .app_wdf_mask                   (32'd0),  // input [31:0]		app_wdf_mask
    // System Clock Ports
    .sys_clk_i                       (sys_clk_i),
    // Reference Clock Ports
    .clk_ref_i                      (clk_ref_i),
    .sys_rst                        (locked) // input sys_rst
    );
    
    
    
ila_0 your_instance_name (
	.clk(ui_clk), // input wire clk


	.probe0(app_wdf_data), // input wire [255:0]  probe0  
	.probe1(app_rd_data), // input wire [255:0]  probe1 
	.probe2(init_calib_complete), // input wire [0:0]  probe2 
	.probe3(READ_FLAG), // input wire [0:0]  probe3 
	.probe4(WRITE_FLAG), // input wire [0:0]  probe4 
	.probe5(app_rd_data_valid), // input wire [0:0]  probe5
    .probe6(cnt_zong), // input wire [31:0]  probe6
    .probe7(cnt_rd) // input wire [31:0]  probe7
);
    
    
    
    
    
    
    
    
    
    
    

    
endmodule
